package com.example.util;

import java.io.ByteArrayOutputStream;
import java.lang.reflect.Field;

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Picture;
import android.graphics.RectF;
import android.graphics.drawable.PictureDrawable;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.webkit.WebView;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;

import com.nostra13.universalimageloader.core.assist.ImageSize;

public class ImageUtil {
	private static final String TAG = "ImageUtil";

	public static byte[] convertBitmapToByteArray(Bitmap bitmap) {
		ByteArrayOutputStream stream = new ByteArrayOutputStream();
		bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
		return stream.toByteArray();
	}

	public static Bitmap convertByteArrayToBitmap(byte[] byteArray) {
		if (byteArray != null)
			return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
		else
			return null;
	}
	
	public static Bitmap getBitmapFromView(View view) {
		view.buildDrawingCache();
		Bitmap bitmap = view.getDrawingCache();
		Bitmap newBitmap = bitmap.copy(bitmap.getConfig(), true);
		view.destroyDrawingCache();
		
		return newBitmap;
	}
	
	public static Bitmap captureSnapshot(final View view, final String file) {
		view.buildDrawingCache();
		Bitmap bitmap = view.getDrawingCache();
		final Bitmap thumbnail = resizeBitmap(bitmap, 200, 200);
		
		new Thread(new Runnable() {
			@Override
			public void run() {
			    boolean result = FileUtil.saveBitmap(thumbnail, file);
			    
//			    view.destroyDrawingCache();
//			    if (!thumbnail.isRecycled())
//			    	thumbnail.recycle();
			    
			    if (result) {
			    	
			    }
			    else {
			    	
			    }
			}
		}).start();
	    
		return bitmap;
	}
	
	public static boolean captureWholeScreen(final WebView view, final String file) {
		Picture picture = view.capturePicture();
		PictureDrawable originalDrawable = new PictureDrawable(picture);
		final Bitmap bitmap = Bitmap.createBitmap(picture.getWidth(), picture.getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        canvas.drawPicture(originalDrawable.getPicture());
        
        new Thread(new Runnable() {
			@Override
			public void run() {
				boolean result = FileUtil.saveBitmap(bitmap, file);
//				view.destroyDrawingCache();
//			    if (!bitmap.isRecycled())
//			    	bitmap.recycle();
			    
			    if (result) {
			    	Log.d("ImageUtil captureWholeScreen", "success");
			    }
			    else
			    	Log.e("ImageUtil captureWholeScreen", "failed");
			}
        	
        }).start();
        
        return (bitmap != null && !bitmap.isRecycled());
	}
	
	public static Bitmap getCapturedWholeScreen(WebView view) {
		Picture picture = view.capturePicture();
		PictureDrawable originalDrawable = new PictureDrawable(picture);
		final Bitmap bitmap = Bitmap.createBitmap(picture.getWidth(), picture.getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        canvas.drawPicture(originalDrawable.getPicture());
        return bitmap;
	}
	
	public static boolean captureScreen(final View view, final String file) {
		view.buildDrawingCache();
		final Bitmap bitmap = view.getDrawingCache();
		
		new Thread(new Runnable() {
			@Override
			public void run() {
				boolean result = FileUtil.saveBitmap(bitmap, file);
//				view.destroyDrawingCache();
//			    if (!bitmap.isRecycled())
//			    	bitmap.recycle();
			    
			    if (result) {
			    	Log.d("ImageUtil captureScreen", "success");
			    }
			    else
			    	Log.e("ImageUtil captureScreen", "failed");
			}
			
		}).start();
	    
		return (bitmap != null && !bitmap.isRecycled());
	}
	
	public static Bitmap getCapturedScreen(final View view) {
		view.buildDrawingCache();
		return view.getDrawingCache();
	}
	
	public static Bitmap getCapturedScreen(final View view, RectF pickedRect) {
		view.buildDrawingCache();
		Bitmap bitmap = view.getDrawingCache();
		
		return Bitmap.createBitmap(bitmap, (int) pickedRect.left, (int) pickedRect.top, (int) (pickedRect.right - pickedRect.left), (int) (pickedRect.bottom - pickedRect.top));
	}
	
	public static Bitmap resizeBitmap(Bitmap bitmap, int width ,int height) {
		int fixedWidth = width, fixedHeight = height;
		if (bitmap.getHeight() > bitmap.getWidth())
			fixedHeight = fixedWidth * bitmap.getHeight() / bitmap.getWidth();
		else
			fixedWidth = fixedHeight * bitmap.getWidth() / bitmap.getHeight();
		
		Bitmap newBitmap = Bitmap.createScaledBitmap(bitmap, fixedWidth, fixedHeight, false);
		return Bitmap.createBitmap(newBitmap, 0, 0, width, height);
	}
	
	public static Bitmap cropCenterBitmap(Bitmap src, int w, int h) {
        if(src == null)
            return null;
        
        int width = src.getWidth();
        int height = src.getHeight();
                
        if(width < w && height < h)
            return src;
        
        int x = 0;
        int y = 0;
        
        if(width > w)
            x = (width - w)/2;
        
        if(height > h)
            y = (height - h)/2;
        
        int cw = w; // crop width
        int ch = h; // crop height
        
        if(w > width)
            cw = width;
        
        if(h > height)
            ch = height;
        
        return Bitmap.createBitmap(src, x, y, cw, ch);
    }
	
	public static Bitmap resizeBitmap(Bitmap bitmap, ImageView targetView) {
		Bitmap newBitmap = null;
		
		try {
			ImageSize targetSize = getImageSizeScaleTo(targetView);
			targetView.setScaleType(ScaleType.CENTER_CROP);
			Log.e(TAG, "bitmap.isRecycled=" + bitmap.isRecycled());
			Log.e(TAG, "targetSize.getWidth()=" + targetSize.getWidth() + " targetSize.getHeight()=" + targetSize.getHeight());
			Log.e(TAG, "targetView.getWidth()=" + targetView.getWidth() + " targetView.getHeight()=" + targetView.getHeight());
			
			int fixedWidth = targetSize.getWidth(), fixedHeight = targetSize.getHeight();
			if (bitmap.getHeight() > bitmap.getWidth())
				fixedHeight = fixedWidth * bitmap.getHeight() / bitmap.getWidth();
			else
				fixedWidth = fixedHeight * bitmap.getWidth() / bitmap.getHeight();
			
			Log.e(TAG, "fixedWidth=" + fixedWidth + " fixedHeight=" + fixedHeight);
			newBitmap = Bitmap.createScaledBitmap(bitmap, fixedWidth, fixedHeight, false);
			
			int x = 0, y = 0; 
			int width = newBitmap.getWidth(), height = newBitmap.getHeight();
			
			if(width > targetSize.getWidth())
	            x = (width - targetSize.getWidth()) / 2;
	        
	        if(height > targetSize.getHeight())
	            y = (height - targetSize.getHeight()) / 2;
	        
	        Log.e(TAG, "x=" + x + " y=" + y);
	        
	        return Bitmap.createBitmap(newBitmap, x, y, targetSize.getWidth(), targetSize.getHeight());
		}
        finally {
        	newBitmap.recycle();	
        }
	}
	
	private static ImageSize getImageSizeScaleTo(ImageView imageView) {
		DisplayMetrics displayMetrics = imageView.getContext().getResources()
				.getDisplayMetrics();
		android.view.ViewGroup.LayoutParams params = imageView
				.getLayoutParams();
		int width = params.width;
		if (width <= 0)
			width = getFieldValue(imageView, "mMaxWidth");
		if (width <= 0)
			width = displayMetrics.widthPixels;
		int height = params.height;
		if (height <= 0)
			height = getFieldValue(imageView, "mMaxHeight");
		if (height <= 0)
			height = displayMetrics.heightPixels;
		return new ImageSize(width, height);
	}
	
	private static int getFieldValue(Object object, String fieldName) {
		int value = 0;
		try {
			Field field = ImageView.class.getDeclaredField(fieldName);
			field.setAccessible(true);
			int fieldValue = (Integer) field.get(object);
			if (fieldValue > 0 && fieldValue < Integer.MAX_VALUE) {
				value = fieldValue;
			}
		} catch (Exception e) {
			Log.e(TAG, e.getMessage(), e);
		}
		return value;
	}

	public static Bitmap getBitmapFromFile(String file) {
		if (!FileUtil.exists(file))
			return null;
		
		return BitmapFactory.decodeFile(file);
	}

	
}
